// internal/api/file_controller.go
package api

import (
	"net/http"
	"strconv"

	"github.com/gin-gonic/gin"

	"github.com/jfastfiler/internal/service"
)

type FileController struct {
	fileService *service.FileService
}

func NewFileController(fileService *service.FileService) *FileController {
	return &FileController{fileService: fileService}
}

// ListFiles 获取文件列表
// @Summary 获取文件列表
// @Description 获取指定路径下的文件列表
// @Tags 文件管理
// @Accept json
// @Produce json
// @Security Bearer
// @Param path query string true "路径"
// @Param page query int false "页码" default(1)
// @Param page_size query int false "每页数量" default(50)
// @Param sort query string false "排序字段" default(name)
// @Param order query string false "排序方向" default(asc)
// @Param name query string false "文件名过滤"
// @Param file_type query string false "文件类型过滤" Enums(image,document,video,audio)
// @Success 200 {object} service.FileListResponse
// @Router /api/v1/files [get]
func (c *FileController) ListFiles(ctx *gin.Context) {
	var req service.FileListRequest
	if err := ctx.ShouldBindQuery(&req); err != nil {
		ctx.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	userID := ctx.GetInt("user_id")
	resp, err := c.fileService.ListFiles(userID, &req)
	if err != nil {
		ctx.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	ctx.JSON(http.StatusOK, resp)
}

// UploadFile 上传文件
// @Summary 上传文件
// @Description 上传文件到指定路径
// @Tags 文件管理
// @Accept multipart/form-data
// @Produce json
// @Security Bearer
// @Param path formData string true "上传路径"
// @Param file formData file true "文件"
// @Param description formData string false "文件描述"
// @Param tags formData string false "文件标签，用逗号分隔"
// @Param overwrite formData bool false "是否覆盖已存在文件" default(false)
// @Success 200 {object} service.UploadResponse
// @Router /api/v1/files/upload [post]
func (c *FileController) UploadFile(ctx *gin.Context) {
	path := ctx.PostForm("path")
	description := ctx.PostForm("description")
	tagsStr := ctx.PostForm("tags")
	overwrite := ctx.PostForm("overwrite") == "true"

	file, err := ctx.FormFile("file")
	if err != nil {
		ctx.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	// 解析标签
	var tags []string
	if tagsStr != "" {
		tags = strings.Split(tagsStr, ",")
	}

	userID := ctx.GetInt("user_id")
	req := &service.UploadRequest{
		Path:        path,
		File:        file,
		Description: description,
		Tags:        tags,
		UserID:      userID,
		Overwrite:   overwrite,
	}

	resp, err := c.fileService.Upload(req)
	if err != nil {
		ctx.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	ctx.JSON(http.StatusOK, resp)
}

// CreateDirectory 创建目录
// @Summary 创建目录
// @Description 在指定路径下创建新目录
// @Tags 文件管理
// @Accept json
// @Produce json
// @Security Bearer
// @Param data body service.CreateDirectoryRequest true "目录信息"
// @Success 200 {object} gin.H
// @Router /api/v1/files/mkdir [post]
func (c *FileController) CreateDirectory(ctx *gin.Context) {
	var req service.CreateDirectoryRequest
	if err := ctx.ShouldBindJSON(&req); err != nil {
		ctx.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	userID := ctx.GetInt("user_id")
	err := c.fileService.CreateDirectory(userID, req.Path, req.Name)
	if err != nil {
		ctx.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	ctx.JSON(http.StatusOK, gin.H{"message": "目录创建成功"})
}

// BatchOperation 批量操作
// @Summary 批量操作
// @Description 对文件进行批量操作（删除、移动、复制、重命名）
// @Tags 文件管理
// @Accept json
// @Produce json
// @Security Bearer
// @Param operation body service.BatchOperation true "操作信息"
// @Success 200 {object} gin.H
// @Router /api/v1/files/batch [post]
func (c *FileController) BatchOperation(ctx *gin.Context) {
	var op service.BatchOperation
	if err := ctx.ShouldBindJSON(&op); err != nil {
		ctx.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	userID := ctx.GetInt("user_id")
	if err := c.fileService.BatchOperation(userID, &op); err != nil {
		ctx.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	ctx.JSON(http.StatusOK, gin.H{"message": "操作完成"})
}

// DownloadFile 下载文件
// @Summary 下载文件
// @Description 下载指定文件
// @Tags 文件管理
// @Produce octet-stream
// @Security Bearer
// @Param id path int true "文件ID"
// @Success 200 {file} binary
// @Router /api/v1/files/download/{id} [get]
func (c *FileController) DownloadFile(ctx *gin.Context) {
	fileID, err := strconv.Atoi(ctx.Param("id"))
	if err != nil {
		ctx.JSON(http.StatusBadRequest, gin.H{"error": "无效的文件ID"})
		return
	}

	userID := ctx.GetInt("user_id")
	filePath, err := c.fileService.PrepareDownload(userID, fileID)
	if err != nil {
		ctx.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	// 设置下载头
	ctx.FileAttachment(filePath, filepath.Base(filePath))
}

// GetFileInfo 获取文件信息
// @Summary 获取文件信息
// @Description 获取文件的详细信息
// @Tags 文件管理
// @Produce json
// @Security Bearer
// @Param id path int true "文件ID"
// @Success 200 {object} model.FileMetadata
// @Router /api/v1/files/{id} [get]
func (c *FileController) GetFileInfo(ctx *gin.Context) {
	fileID, err := strconv.Atoi(ctx.Param("id"))
	if err != nil {
		ctx.JSON(http.StatusBadRequest, gin.H{"error": "无效的文件ID"})
		return
	}

	userID := ctx.GetInt("user_id")
	file, err := c.fileService.GetFileInfo(userID, fileID)
	if err != nil {
		ctx.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	ctx.JSON(http.StatusOK, file)
}